package com.gitee.ipo.system.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.ipo.system.entity.IpoDocInfo;
import com.gitee.ipo.system.entity.search.DocEntity;
import com.gitee.ipo.system.entity.search.IpoDocInfoSearch;
import com.gitee.ipo.system.entity.search.SearchDTO;
import com.gitee.ipo.system.entity.search.SearchRequest;
import com.gitee.ipo.system.entity.star.IpoDocUserStar;
import com.gitee.ipo.system.mapper.IpoDocInfoMapper;
import com.gitee.ipo.system.service.IpoDocInfoService;
import com.gitee.ipo.system.service.IpoDocUserStarService;
import com.google.common.base.Splitter;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.assertj.core.util.Lists;
import org.frameworkset.elasticsearch.boot.BBossESStarter;
import org.frameworkset.elasticsearch.client.ClientInterface;
import org.frameworkset.elasticsearch.entity.ESDatas;
import org.frameworkset.elasticsearch.entity.RestResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;


/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author acao
 * @since 2024-02-08
 */
@Service
public class IpoDocInfoServiceImpl extends ServiceImpl<IpoDocInfoMapper, IpoDocInfo> implements IpoDocInfoService {

    private static final String mappath = "esmapper/ipoDoc.xml";

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Autowired
    private BBossESStarter bbossESStarter;

    @Autowired
    private IpoDocUserStarService ipoDocUserStarService;


    @Override
    public List<IpoDocInfoSearch> getIpoDoc(SearchRequest searchRequest) {
        List<IpoDocInfoSearch> result = new ArrayList<>();
        String path = "doc_info_01/_search";
        ClientInterface restClient = bbossESStarter.getConfigRestClient(mappath);
        SearchDTO searchDTO = new SearchDTO();
        String secCodes = searchRequest.getSecCodes();
        String title = searchRequest.getTitle();
        String content = searchRequest.getContent();
        int page = searchRequest.getPage();
        searchDTO.setPageNum(page);
        if (StringUtils.isNotBlank(secCodes)) {
            searchDTO.setSecCodes(Lists.newArrayList(secCodes));
        }
        if (StringUtils.isNotBlank(title)) {
            List<String> titles = Splitter.on(Pattern.compile("\\s")).omitEmptyStrings().splitToList(title);
            searchDTO.setTitle(titles);
        }
        if (StringUtils.isNotBlank(content)) {
            List<String> contents = Splitter.on(Pattern.compile("\\s")).omitEmptyStrings().splitToList(content);
            searchDTO.setContent(contents);
        }

        ESDatas<IpoDocInfoSearch> queryByDemo = restClient.searchList(path, "queryDoc", searchDTO, IpoDocInfoSearch.class);
        if (CollectionUtils.isEmpty(result = queryByDemo.getDatas())) {
            return result;
        }

        //处理标红
        List<Map<String, Object>> seccode = queryByDemo.getAggregationBuckets("seccode");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        int loginId = StpUtil.getLoginIdAsInt();
        for (IpoDocInfoSearch ipoDoc : result) {
            //查询是否收藏
            Boolean star = isStar(loginId, Long.parseLong(ipoDoc.getDoc_id()));
            ipoDoc.setStar(star);
            ipoDoc.setSize(queryByDemo.getTotalSize());

            ipoDoc.setSecCodeStr(ipoDoc.getSecCode() + "/" + ipoDoc.getSecName());
            if (!CollectionUtils.isEmpty(seccode)) {
                ipoDoc.setStockNum(seccode.size());
            }
            if (Objects.nonNull(ipoDoc.getPubdate())) {
                ipoDoc.setPubdateStr(simpleDateFormat.format(ipoDoc.getPubdate()));
            }
            Map<String, List<Object>> highlightMap = ipoDoc.getHighlight();
            if (highlightMap != null) {
                StringBuilder conSb = new StringBuilder(), titilSb = new StringBuilder();
                List<Object> hContent = highlightMap.get("content");
                List<Object> htitle = highlightMap.get("title");
                if (!CollectionUtils.isEmpty(hContent)) {
                    for (Object aContent : hContent) {
                        conSb.append(aContent).append("</br>");
                    }
                    ipoDoc.setDigest(conSb.toString());
                }
                if (!CollectionUtils.isEmpty(htitle)) {
                    for (Object t : htitle) {
                        titilSb.append(t).append("</br>");
                    }
                    ipoDoc.setTitle(titilSb.toString());
                }
            }
        }

        return result;
    }

    private Boolean isStar(int loginId, Long docId) {
        QueryWrapper<IpoDocUserStar> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", loginId).eq("doc_id", docId).last("limit 1");

        IpoDocUserStar ipoDocUserStar1 = ipoDocUserStarService.getOne(wrapper);
        return Objects.nonNull(ipoDocUserStar1);
    }

    @Override
    public IpoDocInfoSearch getIpoDocOne(String docId) {
        String path = "doc_info_01/_search";
        ClientInterface restClient = bbossESStarter.getConfigRestClient(mappath);
        IpoDocInfoSearch ipoDocInfoSearch = new IpoDocInfoSearch();
        ipoDocInfoSearch.setDoc_id(docId);
        ESDatas<IpoDocInfoSearch> queryDoc2 = restClient.searchList(path, "queryDoc2", ipoDocInfoSearch, IpoDocInfoSearch.class);

        return queryDoc2.getDatas().get(0);
    }

    @Override
    public String saveIpoDoc() {
        if (atomicInteger.get() == 0) {
            ClientInterface restClient = bbossESStarter.getConfigRestClient(mappath);
            List<IpoDocInfo> list = list();
            for (IpoDocInfo ipo : list) {

                IpoDocInfoSearch ipoDocInfoSearch = new IpoDocInfoSearch(ipo.getId() + "", ipo.getSeccode(), ipo.getSecname(), ipo.getTitle(),
                        null, ipo.getPubdate(), ipo.getDownpath());
                String content = parsePDF(ipo.getDownpath());
                if (content == null || content == "") {
                    continue;
                }
                int index = 100;
                if (content.length() <= 100) {
                    index = content.length();
                }
                String digest = content.substring(0, index);
                ipoDocInfoSearch.setDigest(digest);
                ipoDocInfoSearch.setContent(content);
                restClient.addDocument("doc_info_01", "_doc", ipoDocInfoSearch);
            }
        }

        atomicInteger.incrementAndGet();
        return "sucess";
    }

    public String parsePDF(String filePath) {
        String text;
        try {
            URL url = new URL(filePath);
            try (InputStream inputStream = url.openStream(); // 打开网络文件的输入流
                 PDDocument document = PDDocument.load(inputStream)) { // 加载PDF到PDDocument

                if (!document.isEncrypted()) { // 检查PDF是否加密
                    PDFTextStripper stripper = new PDFTextStripper(); // 创建PDFTextStripper实例
                    text = stripper.getText(document); // 提取文本内容
                    text = text.replaceAll("\\n", " ")
                            .replaceAll("\\t", " ")
                            .replaceAll("\\r", " ");
                } else {
                    throw new IOException("文档已加密，无法读取。");
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }

        return text;
    }


    /**
     * 文件下载
     *
     * @param downloadUrl 源文件地址
     * @param response
     */
    @Override
    public void downloadFile(String downloadUrl, HttpServletResponse response, HttpServletRequest request) {
        try {
            //获取文件名称
            String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
            // 浏览器
            String browser = request.getHeader("User-Agent").toUpperCase();

            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + browserFileName(browser, fileName));
            //开始下载
            BufferedInputStream is = new BufferedInputStream(new URL(downloadUrl).openStream());
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[1024];
            int len;
            while ((len = is.read(buff, 0, buff.length)) != -1) {
                out.write(buff, 0, len);
            }
            is.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public String browserFileName(String browser, String fileName) {
        String result = "";
        try {
            if (browser.contains("CHROME")) {
                // 谷歌
                result = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
            } else if ((browser.contains("FIREFOX"))) {
                // firefox浏览器
                result = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
            } else if (browser.contains("MSIE") || browser.contains("TRIDENT")) {
                // IE浏览器
                result = URLEncoder.encode(fileName, "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    public static void main(String[] args) {
        List<String> list = Splitter.on(Pattern.compile("\\s")).omitEmptyStrings().splitToList("zhangsan   lisi   wangwu liu");
        System.out.println(list);
    }
}
